package com.lemon.cloud.curator.config;

import com.lemon.cloud.curator.lock.CuratorDistributedLock;
import com.lemon.cloud.lock.DistributedLock;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lemon
 * @version 1.0
 * @description: TODO
 * @date Create by lemon on 2019-09-12 12:57
 */
@Slf4j
@Configuration
@ConditionalOnClass({CuratorFrameworkFactory.class})
@EnableConfigurationProperties({CuratorProperties.class})
public class CuratorAutoConfiguration {
    /**
     * @param curatorProperties
     * @return org.apache.curator.framework.CuratorFramework
     * @description 获取 CuratorFramework，使用 curator 操作 zookeeper
     * @author lemon
     * @date 2019-09-12 12:59
     */
    @Bean
    public CuratorFramework curatorFramework(CuratorProperties curatorProperties) {
        // 配置zookeeper连接的重试策略
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(curatorProperties.getElapsedTimeMs(), curatorProperties.getRetryCount());

        // 构建 CuratorFramework
        CuratorFramework curatorFramework =
                CuratorFrameworkFactory.builder()
                        .connectString(curatorProperties.getConnectString())
                        .sessionTimeoutMs(curatorProperties.getSessionTimeoutMs())
                        .connectionTimeoutMs(curatorProperties.getConnectionTimeoutMs())
                        .retryPolicy(retryPolicy)
                        .build();
        // 连接 zookeeper
        curatorFramework.start();
        log.info("Create zookeeper CuratorFramework");
        return curatorFramework;
    }

    @Bean
    @ConditionalOnMissingBean
    public DistributedLock curatorDistributedLock(CuratorFramework curatorFramework) {
        CuratorDistributedLock curatorDistributedLock = new CuratorDistributedLock();
        curatorDistributedLock.setCuratorFramework(curatorFramework);
        log.info("Create a distributed lock CuratorDistributedLock");
        return curatorDistributedLock;
    }
}
